#!/usr/bin/env python

import sys
import string
import os


## Set of terminal colors

def color(t, c):
    return chr(0x1b)+"["+str(c)+"m"+t+chr(0x1b)+"[0m"
def black(t):
    return color(t, 30)
def red(t):
    return color(t, 31)
def green(t):
    return color(t, 32)
def yellow(t):
    return color(t, 33)
def blue(t):
    return color(t, 34)
def mangenta(t):
    return color(t, 35)
def cyan(t):
    return color(t, 36)
def white(t):
    return color(t, 37)
def bold(t):
    return color(t, 1)



## taken from http://mail.python.org/pipermail/python-list/2000-May/033365.html

def ttysize():
    fp = os.popen('stty -a', 'r')
    ln1 = fp.readline()
    fp.close()
    if not ln1:
        raise ValueError, 'tty size not supported for input'
    vals = {'rows':None, 'columns':None}
    for ph in string.split(ln1, ';'):
        x = string.split(ph)
        if len(x) == 2:
            vals[x[0]] = x[1]
            vals[x[1]] = x[0]
    return vals['columns']

ttywidth = int(ttysize())

# fallback to 80
if ttywidth == 0: ttywidth = 80


## taken from http://code.activestate.com/recipes/134892/

class _Getch:
    """Gets a single character from standard input.  Does not echo to the
screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            try:
                self.impl = _GetchMacCarbon()
            except ImportError:
                self.impl = _GetchUnix()

    def __call__(self): return self.impl()


class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()

class _GetchMacCarbon:
    """
    A function which returns the current ASCII key that is down;
    if no ASCII key is down, the null string is returned.  The
    page http://www.mactech.com/macintosh-c/chap02-1.html was
    very helpful in figuring out how to do this.
    """
    def __init__(self):
        import Carbon
        Carbon.Evt #see if it has this (in Unix, it doesn't)

    def __call__(self):
        import Carbon
        if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask
            return ''
        else:
            #
            # The event contains the following info:
            # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
            #
            # The message (msg) contains the ASCII char which is
            # extracted with the 0x000000FF charCodeMask; this
            # number is converted to an ASCII character with chr() and
            # returned
            #
            (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
            return chr(msg & 0x000000FF)


getch = _Getch()
